I want to index container types using a generic form of indexData
and have that index desire be valid in multiple contexts
Given tuple[ containerType, indexData]
:
9= I want to index into an instance of containerType
in python memory
5= I want to index into an arbitrary ConversionSet
serialised format, many of these inherit behaviour from each other so they can copy the indexing definitions from another and edit them
Considering that object instances with variables stored upon them are containers, I also wish to index into these
Given that a very large portion of python objects follow this format, it is not useful to specify the type here which could be left as None
The rest of in memory indexing of container types seems to be done using square brackets although some may involve a specific function.
I may implement a container type which uses container.get( index)
, i may implement a complex one which uses container.getRecursive( mode: Mode, index0: int, index1: externalLibraryType)[ index2]
So at least within python memory we have to support ( d= ( o.i
| getattr( o, i)
), f= o[ i]
, g= A custom function)
So if we are passing none type then we can use d, if passing a non custom type then we can use f
when describing a custom type, we may want to use g or a variation of d, f
for g we need to reference a function, state where the
maybe the custom definition in python should just be a function which takes the instance and input data and returns the rertrieved data
would this play nicely with other forms of retrieval?
well we could follow through with the getRecursive
scenario
GenericTypeConversion
uses solely []
indexing. Converted instances of python objects are accessed by instance[ attributeName]
due to the behaviour of getDictFromObjectInstance
Converted instances of python objects using custom conversion mechanisms need to also define how to convert the same indexData
into the new
They could define a function which takes the instance and the indexData
however we need to be able to translate this into a format perceptable by the database, with mongodbs dot notation being a goal here.
So maybe it can return a list of items, each prefaced by an enum describing the indexing method, i will write an example for tuples in the GenericTypeConversion
Examples
class IndexType( IntFlag):
MEMBER= auto()
SQUARE_BRACKET= auto()
CUSTOM_FUNCTION= auto()
@dataclass
class IndexData:
indexIntoIndexData: int| None| slice= None
-
generic object instance: passed index:
( None, "tree")
in memory indexing definition: implied indexing of[ [ MEMBER, IndexData()]]
GenericTypeConversion
indexing definition: indexing of[ [ SQUARE_BRACKET, IndexData()]]
mongodb interpretation:".tree"
- If we wanted the indexed object to be referred to as a list instead of an object instance we could pass `( list, "tree")` as the index
-
fallback: passed index:
( unknownType65, ( scrambleyammo))
in memory indexing definition: implied indexing of[ [ SQUARE_BRACKET, IndexData()]]
GenericTypeConversion
indexing definition: passthrough indexing to in memory indexing definition mongodb interpretation:".{str(( scrambleyammo))}"
- use string conversion in Utils -
tuple: passed index:
( tuple, 9)
in memory indexing definition: none needed as it complies with the fallbackGenericTypeConversion
indexing definition: taken from the custom conversion definition[ [ SQUARE_BRACKET, "tuple"], [ SQUARE_BRACKET, IndexData()]]
mongodb interpretation:"tuple.9"
complex scenario conversion function
class ComplexType:
getRecursive( mode: Mode, n: int, tr: externalLibraryType):...
@classmethod
getRecursiveFromDictRep( dictRep: dict, mode: Mode, n: int, tr: externalLibraryType):...
def getComplexTypeIndex( instance: ComplexType, indexData):
return instance.getRecursive( indexData[ 2], indexData[ 0], cheese)[ indexData[ 1]]
def getComplexTypeIndexFromDictRep( instance: dict, indexData):
return ComplexType.getRecursiveFromDictRep( instance, indexData[ 2], indexData[ 0], cheese)[ indexData[ 1]]
-
complex scenario: passed index:
( ComplexType, ( 55, "cheese", MODE.FORWARD, "nice!"))
in memory indexing definition:[ [ CUSTOM_FUNCTION, getComplexTypeIndex, IndexData( slice( 0, 3))], [ SQUARE_BRACKET, IndexData( 3)]]
GenericTypeConversion
indexing definition: despite me currently not being able to think of a use case this could be defined as[ [ CUSTOM_FUNCTION, getComplexTypeIndexFromDictRep, IndexData( slice( 0, 3))], [ SQUARE_BRACKET, IndexData( 3)]]
mongodb interpretation: this is unable to be represented within mongodb dot notation as python code cannot be called there -
dict: passed index:
( dict, "cheese")
in memory indexing definition: none needed as it complies with the fallbackGenericTypeConversion
indexing definition: none defined so it passes through to the in memory definition mongodb interpretation:"dict.cheese"
A function can then be written to interpret
def returnContainedWithContainedDescription( container, containedDescription: None| slice| Any):
if containedDescription== None:
return container
elif isinstance( containedDescription, slice):
start, stop, step= containedDescription.indices( len( container))
return container[ start: stop: step]
else:
return container[ containedDescription]
# Maybe we can call a flatten function first which substitutes the indexData in
# Maybe this could be made generic so there isnt any logic tied to the indexing method, we know that the first member of each index operation is the index operations enum
def flattenIndexingDefinition( objectInstance, indexData, indexingDefinition):
for level in indexingDefinition:
if level[ 0]== IndexType.CUSTOM_FUNCTION:
indexDataIndex= 2
else:
indexDataInsex= 1
if isinstance( level[ indexDataIndex], IndexData):
currentLevelFinalIndexData= returnContainedWithContainedDescription( indexData, level[ indexDataIndex].indexIntoIndexData)
level[ indexDataIndex]= currentLevelFinalIndexData
return indexingDefinition
def interpretIndexingDefinition( objectInstance, indexData, indexingDefinition):
indexingDefinition= flattenIndexingDefinition( objectInstance, indexData, indexingDefinition)
returned= objectInstance
for level in indexingDefinition:
if level[ 0]== IndexType.MEMBER:
returned= getattr( returned, level[ 1])
elif level[ 0]== IndexType.SQUARE_BRACKET:
returned= returned[ level[ 1]]
elif level[ 0]== IndexType.CUSTOM_FUNCTION:
returned= level[ 1]( returned, level[ 2])
return returned
maybe saving custom index data for a conversion can be related to the type being converted to,
need a way to override both fallback and object instance indexingDefinitions
need a way to state that a type is not indexable in a specific domain
need a way to state that a domain does not support custom functions, maybe also to state that it doesnt support other definition types
so I need a way of potentially "splitting" the indexingDefinition
So on the JsonCompliantDictionary
, we are inheriting the fallback definition for dict
, well we can set up a system which changes the definition depending on the passed key. Here we could use that to say that keys that are not instances of str
return a NONE value or something like that
what about interpreting the definition, how does this solution work with interpreting the definition
also what of interpreting the instance being relevant
i think maybe we just care about the key
if this is the case then we need a way of describing whether it is key dependant or not, maybe this can be combined with the not supported declaration to obtain 3 different enum values
Generalisability
So the current design is to describe indexing into containers, it is specific to python currently due to the usage of p= ( members, square brackets, custom functions) We can transform between different representations of that data but we are still modelling using the python conventions of p. What is needed to transfer this understanding to other non python understandings of the nature of indexing is to transform between instances of the "thing" that p is I was going to do a manual transformation from the python format into mongodbs dot notation format but i could use this mindset to do the transformation. These could be called indexing method collections as each one can provide its own set of indexing methods So if we are defining different representations of data as in ( python memory instances, python dict rep of that same data, python json compliant dict rep of that data) is this different enough to describing another instance of my brain is bad rn i have runny nose and pounding brain rrrrrrrr let it be known that i still think discrete thought is a bottleneck, all natural language is bad, dont get too sucked in to the game I dont think the other shit matters enough right now, good large scale code alteration tools are needed for big changes in the future, increase the rate of production instead of just producing like a dumb dumb, yeab good luck getting to the moon with that hoe, fucker So ignore this
What of indexing into delta transform sets,
Do this, mongos dot notation and possible tabular or sql indexing form a need for implementing # Generalisability Maybe just discuss indexing into delta transform sets first And also get other design such as that discussed in # Code that needs to be written done first to reduce mental load
Indexing into delta transformation sets as an IndexingMethod
makes sense as it is data
An issue with using them to construct new versions without loading the versions into memory is that one isnt checking the validity of the index path and so we would have to check for and either prune or disregard invalid delta transforms upon loading
So we are given a sequence of index s. Each of which are in the form tuple[ type, indexData]
and it would be useful to transform this into a sequence of delta transform operations. The delta transformation set would be decided by the index s type. And the delta transformation set would have to declare ( that it is a container type, the specific operation that will be used, the mapping from the index data to the operation data)
complex behaviour may be required to do this so maybe the conversion set can optionally support it and then provide the relevant information through the return value of a function
the description format could be just the operation there is no need for index data placeholder ( SequenceMatcher, ( "change", ( relevantData)))
to obtain this we must calculate the index. we cant convert from the python method as we need the python type information
Code that needs to be written
Aspects associated with the python indexing method can be marked with ^
Need to define the data format used to model within using MutableSequence
s as well as defining the IndexData
placeholder
( ^) Need to define the different python contained obtenance methods: MEMBER, SQUARE_BRACKET, CUSTOM_FUNCTION
( ^) Need to write associated deconstruction method, interpretIndexingDefinition
above
( ^) Need to specify the in python loaded set with defaults for ( types with members), ( fallback). Need to be able to specify custom behaviour for in memory indexing here too
Need to be able to specify an arbitrary number of different indexing contexts all of which have their own definitions of both special types, ( MEMBERED_INSTANCE
, FALLBACK
), and custom types.
These could either use indexing systems to inherit definitions or they could use a plethora of methods to do so
the latter seems best as they may wish to inherit from differing places
It seems like IndexingContext
s should implement custom functionality to populate their Mapping[ type| Special, IndexingDescription]
These are all inherently associated with a `IndexingMethod`
obtenance methods are defined on the possible `IndexingMethod`
how about special types? Are they on the `IndexingMethod` or the `IndexingContext`?
Maybe the designation that designated ( `MEMBERED_INSTANCE`, `FALLBACK`, other) would find some reason in the future to designate differently depending on the known information at the time
It does seem specific to python, I fall with just placing it within the `IndexingMethod` currently
BECAUSE SPECIALS NEED TO BE PASSED IN THE INDEX INSTEAD OF A TYPE THEY NEED TO BE UNIVERSAL, NO THEY DONT, FALLBACK IS DECIDED BY THE INDEXINGMETHOD NOT PASSED, MEMBER IS PASSED THOUGH,
HOW TO GET AROUND THIS?
WELL IF WE ARE PASSING A
Need a way of specifying that an index description for a type is dependant on the passed key, then need to define a function which takes the key and returns a description Need to be able to take ( a sequence of indexs, a context, a possible method ( although the contexts are associated with methods already)) and return the index description. If impossible to find the indexing description, an impassible obstacle in the path. Then the caller needs to be notified. This can also call the custom function should a key dependant description be defined for a type ( ^) Need to be able to interpret the special types as opposed to the custom defined ones. in ^ we need to be given a type or enum and then return the relevant indexing definition using an order specific to ^
How to implement special cases regarding notes above and below
So index sequences passed to resolveIndexSequenceForContext
need to be universal regardless of the indexing method that is tied to the passed indexing context
The same combination of types and indexData can then be used within different indexing methods. All of the types and type data passed are inherently python related so Not nescessarily, a type could be passed which represents a type in another system, data passed could be representative of another systems data too this is similar to how an indexing method other than the default python one is representing another systems method of indexing into container data
Therefore, ( as long as this indexing system is confined to pytohn) although we are always passing python data, because python is a general modelling language, we can pass things that represent data which doesnt conform to pythons specification, this can be used to represent type s, indexData s, special type s. That conform to perhaps a databases specification
Maybe indexs passed need to be specific to the `IndexingMethod`, yes i think
Also the python method could search for a __getitem__ method on unknown types instead of needing to specify a special
well i was against making them specific but i think it makes sense to make them specific
And so where does this leave my desired ( python method, jsoncompliantdictionary context)-> ( mongo method) conversion
well i need to find the jsoncompliantdictionary description of the given index and then it needs to be passed to a conversion function from ( python method) to ( mongo method).
a= This can be don with a function: ( indexSequence, context, destMethod)-> description
s= it can be done with two:
( indexSequence, context)-> description
( description, startMethod, destMethod)-> description
d= or it can be done this way:
( indexSequence, context)-> description
found, conversions= getDataForType( "indexingDescriptionConversion", startMethod)
if found:
if destMethod in conversions:
conversions[ destMethod]( description)
i think s is best
So given the above indent, special cases and indexing in general should be IndexingMethod
specific
# The first element is the data used to determine how one will index into the data and the second element is data which is used to index into the data
# Methods can support any type here, what the method will listen for is referred to in the Methods, `NotableIndex` variable
Index= Seqeunce[ Any, Any]
@runtime_checkable
class IndexingMethodSupportsDefinitionApplication( Protocol):
def interpretIndexingDefinition( objectInstance: Any, indexData: Any, indexingDefinition: IndexingDescription)-> Any:
...
class IndexingMethod( Protocol):
def resolveIndexSequenceForContext( indexSequence: Sequence[ Index], context: ForwardRef( "IndexingContext"))-> tuple[ bool, Sequence[ IndexingDescription]]:
# Dont currently know if we are taking just one sequence or a tree structure i think just a list of sequences would suffice in a situation where multiple operations must be performed
# Need to get the description using the IndexingMethod
# Need to call any key dependant descriptions
...
class IndexingContext( Protocol):
indexingMethod: IndexingMethod
def convertIndexingDescriptionBetweenMethods( indexingDescription: IndexingMethod.IndexingDescription, sourceMethod, destMethod)-> IndexingMethod.IndexingDescription:
...
# DataForTypes entry:
indexingMethodConversions: dict[ IndexingMethod, Callable[ [ IndexingDesctription], IndexingDescription]]
class PythonInternalIndexingMethod:
IndexData= Any
# The IndexData used as a placeholder in descriptions can be renamed to IndexDataPlaceholder
NotableIndex= tuple[ type| None, IndexData]
# The boolean represents
SingleIndexingDescription= tuple[ ObtenanceMethod, Any, ...]
DefinedIndexingDescription= tuple[ Literal[ False], SingleIndexingDescription]| tuple[ Literal[ True], Callable[ [ Any], SingleIndexingDescription]]
IndexingDescription= Sequence[ SingleIndexingDescription]
class ObtenanceMethod( IntFlag):
MEMBER= auto()
SQUARE_BRACKET= auto()
CUSTOM_FUNCTION= auto()
def interpretIndexingDefinition( objectInstance: Any, indexData: Any, indexingDefinition: IndexingDescription)-> Any:
...
def resolveIndexSequenceForContext( indexSequence: Sequence[ Index], context: IndexingContext)-> tuple[ bool, Sequence[ IndexingDescription]]:
...
class PythonBaseRepresentationIndexingContext:
indexingMethod= PythonInternalIndexingMethod
typeToDescriptionMap: Mapping[ Type| Hashable, IndexingDescription]= # formed from maps provided by type in dataForTypes for the base representation
class GenericTypeConversion:
# IndexingContext protocol implementation
indexingMethod= PythonInternalIndexingMethod
typeToDescriptionMap= # formed from maps provided by type in dataForTypes for the dict representation, no inheritance
class JsonCompliantDictConversion:
# IndexingContext protocol implementation
indexingMethod= PythonInternalIndexingMethod
typeToDescriptionMap= # needs to inherit from GenericTypeConversion and state a key dependant dict conversion
class MongoDBDotIndexingMethod:
NotableIndex= Sequence[ None, Convertable[ str]]
IndexingDescription= str
# Dont really need to interpret the index definition here
# Both a mongodb collection and filter would need to be passed
# the definition would be used in the project field and the result would be returned
# def interpretIndexingDefinition( objectInstance: Any, indexData: Any, indexingDefinition: IndexingDescription)-> Any:
# Just joins all of the indexData together with dots as strings
def resolveIndexSequenceForContext( indexSequence: Sequence[ Index], context: IndexingContext)-> tuple[ bool, Sequence[ IndexingDescription]]:
...
class MongoDBDotIndexingContext:
indexingMethod= MongoDBDotIndexingMethod
def PythonMethodToMongoDBDotMethod( description: PythonInternalIndexingMethod.IndexingDescription)-> Sequence[ bool, MongoDBDotIndexingMethod.IndexingDescription| None]:
constructedStr= ""
first= True
for single in description:
if single[ 0]== PythonInternalIndexingMethod.ObtenanceMethod.CUSTOM_FUNCTION:
return ( False, None)
if not first:
constructedStr+= "."
converted= convert( single[ 1], str)
if converted== None
return ( False, None)
constructedStr+= converted
first= False
return ( True, constructedStr)
class DeltaTransformIndexingMethod:
NotableIndex= Sequence[ type, Any]
IndexingDescription= Sequence[ DeltaTransformationSet, str, Sequence]
# Passed data should be a version data tree and not an object to index into
# Not writing the function now anyway :P fuck you
# def interpretIndexingDefinition( objectInstance: Any, indexData: Any, indexingDefinition: IndexingDescription)-> Any:
# An index here is a tuple[ type, Any] where type is a type as in python
def resolveIndexSequenceForContext( indexSequence: Sequence[ Index], context: IndexingContext)-> tuple[ bool, Sequence[ IndexingDescription]]:
...
class DeltaTransformIndexingContext:
indexingMethod= DeltaTransformIndexingMethod
# Isnt needed as the generating function can be found by resolveIndexSequenceForContext by finding the delta transform set
# typeToDescriptionMap=
an issue in the python method may be that when does the caller know whether to pass the type or None if one knows that member indexing is required in all contexts then they can pass None
an alternative would be to change the fallback type per index, maybe specifying
maybe fallback behavior for python based upon the prescence of __getitem__
in the passed type
we arent converting ( between descriptions) only ( ( index sequence)-> ( description))
it was discussed earlier that custom enum could be used
this would require caller knowledge,
if no definition is found for the context and no fallback is specified then __getitem__
can be used